<template>
  <div
    class="range_scroll_box"
    :style="'height:'+barHeight+'vw;top:-'+barHeight/2+'vw'"
    id="bar_box"
  >
    <div class="range_scroll_wrap" :style="'border-radius:10px'">
      <div
        class="range_touch"
        @touchstart.stop.prevent="onTouch"
        @touchmove.stop.prevent="onTouchMove"
        @touchend.stop.prevent="onTouchEnd"
        id="touchDotEl"
        :style="'width:'+touchWidth+'vw;height:'+touchWidth+'vw;top:-'+touchWidth/2+'vw;left:'+touchDotX+'vw;z-index:99'"
      ></div>
      <div class="range_old" :style="'width:'+progressBarWidth+'vw'"></div>
      <div
        class="range_dot"
        :style="'width:'+dotWidth+'vw;height:'+dotWidth+'vw;top:-'+dotWidth/2+'vw;left:'+progressDotX+'vw;z-index:1'"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  model: {
    prop: "progress",
    event: "change"
  },

  props: {
    random: {
      type: Number,
      required: false
    },
    //进度点的宽度大小，单位vw
    dotWidth: {
      type: Number,
      required: false,
      default: 2.5
    },
    //进度条的高度,单位px,默认5px
    barHeight: {
      type: Number,
      required: false,
      default: 0.5
    },
    //触摸范围的宽度,单位px，默认100px
    touchWidth: {
      type: Number,
      required: false,
      default: 15
    },
    //进度
    progress: {
      type: Number,
      required: true,
      default: 0
    },
    min: {
      type: Number,
      required: false,
      default: 0
    },
    max: {
      type: Number,
      required: false,
      default: 100
    },
    canChangeProgress: {
      type: Boolean,
      required: false,
      default: false
    },
    step: {
      //步距
      type: Number,
      required: false,
      default: 1
    }
  },

  data() {
    return {
      windowWidth: 360,
      barWidth: 300, //进度条的宽度
      progressDotRang: {
        minX: 0,
        maxX: 0
      },
      touchDotRang: {
        minX: 0,
        maxX: 0
      },
      touchStartX: 0, //开始触摸的距离
      touchStartProp: {
        progressDotX: 0,
        touchDotX: 0,
        progressBarWidth: 0
      }, // 暂存触摸开始的时候的位置
      moveDist: 0, //移动的距离
      dotX: 0, // 进度点的坐标,
      _progress: 0,
      progressBarWidth: 0,
      touchDotX: "",
      progressDotX: "",
      touching: false //拖动状态
    };
  },
  watch: {
    progress: {
      handler() {
        if (!this.touching) {
          let p = this.progress;
          if (this.step) {
            p = p * this.step;
          }
          this.caleProgress(p || 0);
        }
      }
    },
    random: {
      handler() {
        this.setup();
      }
    }
  },

  //计算属性
  computed: {},

  methods: {
    //初始化，计算各参数
    setup() {
      this.windowWidth = window.innerWidth;
      let bar = document.getElementById("bar_box");
      this.barWidth = 90; //换算成VW
      this.touchDotRang = {
        minX: 0 - this.touchWidth / 2,
        maxX: this.barWidth - this.touchWidth / 2
      };

      this.progressDotRang = {
        minX: 0 - this.dotWidth / 2,
        maxX: this.barWidth - this.dotWidth / 2
      };
    },
    caleProgress(p) {
      if (p > this.max) {
        p = this.max;
      } //防止客户端反馈进度出错，导致进度条显示错误
      //计算进度
      let prog = (p - this.min) / (this.max - this.min);
      this._progress = prog.toFixed(4); // 保留两位小数

      this.caleBarWidth();
      this.caleTouchDotP();
      this.caleProgressDotP();
    },

    //计算进度条宽度
    caleBarWidth() {
      let w = this.barWidth * this._progress;
      this.progressBarWidth = w;
    },

    //计算触摸点的位置
    caleTouchDotP() {
      let d = this.barWidth * this._progress;
      this.touchDotX = this.touchDotRang.minX + d;
    },

    //计算进度点的位置
    caleProgressDotP() {
      let d = this.barWidth * this._progress;
      this.progressDotX = this.progressDotRang.minX + d;
    },

    //触摸开始事件
    onTouch(e) {
      if (!this.canChangeProgress) return;
      this.$emit("onTouchStart", {});

      this.touching = true;
      this.touchStartX = e.touches[0].clientX; // 记录触摸起始坐标
      this.touchStartProp.progressDotX = this.progressDotX;
      this.touchStartProp.touchDotX = this.touchDotX;
      this.touchStartProp.progressBarWidth = this.progressBarWidth;
    },
    //手指移动事件
    onTouchMove(e) {
      if (!this.canChangeProgress) return;
      this.moveDist = e.touches[0].clientX - this.touchStartX;
      //根据移动距离计算相对窗口移动的距离，单位VW
      let distVW = (this.moveDist / this.windowWidth) * 100;
      let pDotX = this.touchStartProp.progressDotX + distVW;
      if (
        pDotX > this.progressDotRang.minX &&
        pDotX < this.progressDotRang.maxX
      ) {
        this.progressDotX = pDotX;
      }

      let tDotX = this.touchStartProp.touchDotX + distVW;
      if (tDotX > this.touchDotRang.minX && tDotX < this.touchDotRang.maxX) {
        this.touchDotX = tDotX;
      }

      let pBarW = this.touchStartProp.progressBarWidth + distVW;

      if (pBarW > 0 && pBarW < this.barWidth) {
        this.progressBarWidth = pBarW;
      }
    },

    //触摸结束事件
    onTouchEnd(e) {
      if (!this.canChangeProgress) return;
      let pbw = this.progressBarWidth;
      let newProgress = parseInt((pbw / this.barWidth) * this.max);

      if (this.step) {
        let r = parseInt(newProgress / this.step);
        let t = newProgress % this.step;
        if (t > this.step * 0.5) {
          r += 1;
        }
        newProgress = r;
      }

      if (this.step && newProgress == this.progress) {
        //触发界面结算位置
        let p = this.progress;
        if (this.step) {
          p = p * this.step;
        }
        this.caleProgress(p || 0);
      }
      this.$emit("change", newProgress);
      this.$emit("onTouchEnd", {});
      this.touching = false;
    }

    //移动进度条
    //@parms 距离，单位vw
  },
  mounted() {
    this.setup();
    let p = this.progress;
    if (this.step) {
      p = p * this.step;
    }
    this.caleProgress(p || 0);
  }
};
</script>

<style lang="scss" scoped>
.range_scroll_box {
  width: 100%;
  position: relative;
  .range_scroll_wrap {
    width: 100%;
    height: 100%;
    background: #f4f5f7;
  }

  .range_old {
    background-color: #ef7f3a;
    height: 100%;
    border-radius: 10px;
  }

  .range_dot {
    border-radius: 50%;
    background-color: #ef7f3a;
    position: absolute;
  }
  .range_touch {
    border-radius: 50%;
    position: absolute;
  }
}
</style>
